// 第一步：引入需要的组件与方法
import { createVNode, render } from 'vue';

type Caller = <T>(config?: Record<string, any>) => Promise<T>;
type CreateFun = <T>(
  template: any,
  lockScroll?: boolean
) => (config?: Record<string, any>) => Promise<T>;
// 第二步：挂载到dom
// 创建app实例
const createFun: CreateFun = (template, lockScroll = true) => {
  const caller: Caller = (config) => {
    const tem = template;
    let bodyHtml: HTMLCollectionOf<HTMLBodyElement>;
    let originAttr = '';

    if (lockScroll) {
      bodyHtml = document.getElementsByTagName('body');
      originAttr = bodyHtml[0].getAttribute('style') || '';
      const newAttr = `${originAttr}overflow:hidden;`;
      bodyHtml[0].setAttribute('style', newAttr);
    }

    return new Promise((resolve, reject) => {
      const dom = document.createElement('div');

      // 卸载实例，移除dom，去掉滚动锁定
      const removeHidden = () => {
        render(null, dom);
        try {
          document.body.removeChild(dom);
        } catch (error) {
          console.log(
            '🚀 ~ file: apiMount.ts ~ line 33 ~ removeHidden ~ error',
            error
          );
        }

        if (lockScroll) {
          bodyHtml[0].setAttribute('style', originAttr);
        }
      };

      const popstateEvent = () => {
        removeHidden();
        window.removeEventListener('popstate', popstateEvent);
      };

      const vm = createVNode(tem, {
        ...config,
        resolve(val: any) {
          popstateEvent();
          resolve(val);
        },
        close(val: any) {
          popstateEvent();
          reject(val);
        },
      });

      if (window.VueApp) {
        // eslint-disable-next-line no-underscore-dangle
        vm.appContext = window.VueApp._context;
      }

      render(vm, dom);
      document.body.appendChild(dom);
      // 监听路由变化，变化时卸载实例
      window.addEventListener('popstate', popstateEvent);
    });
  };

  return caller;
};

export default createFun;
